#include "tools/list.h"

void list_init(list_t *list)
{
    list->first = list->last = NULL;
    list->count = 0;
}

void list_insert_first(list_t *list, list_node_t *node)
{
    if (!list || !node)
        return;

    node->next = list->first;
    node->pre = NULL;

    if (list_is_empty(list))
        list->first = list->last = node;
    else {
        list->first->pre = node;
        list->first = node;
    }
    list->count++;
}

void list_insert_last(list_t *list, list_node_t *node)
{
    if (!list || !node)
        return;
        
    node->pre = list->last;
    node->next = NULL;

    if (list_is_empty(list))
        list->last = list->first = node;
    else {
        list->last->next = node;
        list->last = node;
    }

    list->count++;
}

list_node_t * list_remove_first(list_t *list)
{
    return list_remove(list, list->first);
}

list_node_t * list_remove_last(list_t *list)
{
    return list_remove(list, list->last);
}

list_node_t * list_remove(list_t *list, list_node_t *remove_node)
{
    if (!list || !remove_node || list_is_empty(list))
        return NULL;

    if (remove_node->next != NULL)
        remove_node->next->pre = remove_node->pre;
    if (remove_node->pre != NULL) 
        remove_node->pre->next = remove_node->next;

    if (list->first == remove_node)
        list->first = remove_node->next;
    if (list->last == remove_node)
        list->last = remove_node->pre;
    
    remove_node->next = remove_node->pre = NULL;
    list->count--;

    return remove_node;
}
